/********************************************************************************
 * ListingOptionsServiceDelegator.java
 *
 * Created by Jigar Mistry
 * Last modified Date: Sep 8, 2008 2:00:28 PM by Jigar Mistry
 * Version : 0.1
 * Copyright (c) 2008 - 2009 cyberThink Infotech Pvt. Ltd., All rights reserved.
 ********************************************************************************/
package com.printeverywhere.delegator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import static com.printeverywhere.util.AdminConstants.ERROR_GET_LIST_WITHOUT_SEARCH_CRITERIA;
import static com.printeverywhere.util.AdminConstants.GET_LIST_WITHOUT_SEARCH_CRITERIA;
import static com.printeverywhere.util.AdminConstants.GET_LIST_WITH_SEARCH_LIST_CRITERIA;
import static com.printeverywhere.util.AdminConstants.SESSION_CLOSED;
import static com.printeverywhere.util.AttributeConstants.*;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.printeverywhere.dto.Itemtype;
import com.printeverywhere.dto.ListingOptions;
import com.printeverywhere.dto.LocationCategories;
import com.printeverywhere.util.HibernateUtil;
import com.printeverywhere.util.SearchListCriteria;

public class ListingOptionsServiceDelegator {
	private static Logger log = Logger.getLogger(ListingOptionsServiceDelegator.class);

	@SuppressWarnings("unchecked")
	public static ListingOptions getListingOptions() throws HibernateException {
		if(log.isInfoEnabled()){
			log.info("Getting list for ListingOptions without search criteria".intern());
		}
		Session session = HibernateUtil.getSession();
		try {
			Transaction transaction = session.beginTransaction();
			List<ListingOptions> ListingOptionsList = session.createCriteria(ListingOptions.class).list();
			transaction.commit();
			return (ListingOptionsList.size() > 0) ? ListingOptionsList.get(0) : new ListingOptions();
		} catch (HibernateException e) {
			log.error("Got exception when getting list for ListingOptions without search criteria".intern());
			throw e;
		} finally {
			if(log.isInfoEnabled()){
				log.info(CLOSING_SESSION);
			}
			session.flush();
			session.close();
		}
	}

	/**
	 * Update mailing system.
	 *
	 * @param listingOptions the mailing system
	 *
	 * @throws HibernateException the hibernate exception
	 */
	public static void updateListingOptions(ListingOptions listingOptions) throws HibernateException {
		if(log.isInfoEnabled()){
			log.info("Called updateListingOptions method".intern());
		}
		Session session = HibernateUtil.getSession();
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			session.saveOrUpdate(listingOptions);
			transaction.commit();
		} catch (HibernateException e) {
			log.error("Got exception when update ListingOptions without search criteria".intern());
			if (transaction != null)
				transaction.rollback();
			throw e;
		} finally {
			if(log.isInfoEnabled()){
				log.info(CLOSING_SESSION);
			}
			session.flush();
			session.close();
		}
	}

	/**
	 * Update mailing system.
	 *
	 * @param homepageFeaturedListsSettings the mailing system
	 *
	 * @throws HibernateException the hibernate exception
	 */
	public static void updateHomepageListSettings(Itemtype homepageFeaturedListsSettings) throws HibernateException {
		if(log.isInfoEnabled()){
			log.info("Called updateHomepageListSettings method".intern());
		}
		Session session = HibernateUtil.getSession();
		Transaction transaction = null;
		try {
			transaction = session.beginTransaction();
			session.update(homepageFeaturedListsSettings);
			transaction.commit();
		} catch (RuntimeException e) {
			log.error("Got exception when update Itemtype without search criteria".intern());
			if (transaction != null)
				transaction.rollback();
			throw e;
		} finally {
			if(log.isInfoEnabled()){
				log.info(CLOSING_SESSION);
			}
			session.flush();
			session.close();
		}
	}

	/**
	 * Gets the list of all the records from HomepageFeaturedListsSettings table without
	 * checking any predefined criteria, It simply list all the rows from
	 * database table.
	 *
	 * @return the list
	 * @throws HibernateException
	 *             the hibernate exception
	 */
	public static List<Itemtype> getHomepageFeaturedListsSettingsList() throws HibernateException {
		log.info(GET_LIST_WITHOUT_SEARCH_CRITERIA);
		Session session = HibernateUtil.getSession();
		Transaction transaction = session.beginTransaction();
		try {
			List<Itemtype> list = session.createCriteria(
					Itemtype.class).list();
			transaction.commit();
			return list;
		} catch (HibernateException e) {
			log.error(ERROR_GET_LIST_WITHOUT_SEARCH_CRITERIA
					+ e.getMessage());
			transaction.rollback();
			throw e;
		} finally {
			log.info(SESSION_CLOSED);
			session.close();
		}
	}

	public static void main(String[] args) {
		List<Itemtype> homepageFeaturedListsSettingsList = ListingOptionsServiceDelegator
		.getHomepageFeaturedListsSettingsList();
		System.out.println(" --> "+ homepageFeaturedListsSettingsList.size());
	}
	/**
	 * Returns the list of the HomepageFeaturedListsSettings based on the conditions
	 * specified in searchListCriteria. It checks for the given values equality,
	 * non-equality, greater, less, like, ...etc. operations.
	 *
	 * @param searchCriteria
	 *            the search criteria
	 * @return the list
	 * @throws HibernateException
	 *             the hibernate exception
	 */
	public static List<Itemtype> getList(
			SearchListCriteria searchCriteria) throws HibernateException {
		log.info(GET_LIST_WITH_SEARCH_LIST_CRITERIA);
		Session session = HibernateUtil.getSession();
		Criteria criteria = session.createCriteria(Itemtype.class);
		String orderBY = searchCriteria.getOrderBy();
		if (orderBY != null) {
			if (searchCriteria.isAsc()) {
				criteria.addOrder(Order.asc(orderBY));
			} else {
				criteria.addOrder(Order.desc(orderBY));
			}
		}
		Set<String> keys = searchCriteria.getAttributeNames();
		Iterator<String> it = keys.iterator();
		String key = null;
		Object[] value = null;
		while (it.hasNext()) {
			key = it.next();
			value = searchCriteria.getAttribute(key);
			if (((String) value[1]).equals(SearchListCriteria.EQ)) {
				criteria.add(Restrictions.eq(key, value[0]));
			} else if (((String) value[1]).equals(SearchListCriteria.GE)) {
				criteria.add(Restrictions.ge(key, value[0]));
			} else if (((String) value[1]).equals(SearchListCriteria.GT)) {
				criteria.add(Restrictions.gt(key, value[0]));
			} else if (((String) value[1]).equals(SearchListCriteria.ILIKE)) {
				criteria.add(Restrictions.ilike(key, value[0]));
			} else if (((String) value[1]).equals(SearchListCriteria.ISNOTNULL)) {
				criteria.add(Restrictions.isNotNull(key));
			} else if (((String) value[1]).equals(SearchListCriteria.ISNULL)) {
				criteria.add(Restrictions.isNull(key));
			} else if (((String) value[1]).equals(SearchListCriteria.LE)) {
				criteria.add(Restrictions.le(key, value[0]));
			} else if (((String) value[1]).equals(SearchListCriteria.LIKE)) {
				criteria.add(Restrictions.like(key, value[0]));
			} else if (((String) value[1]).equals(SearchListCriteria.LT)) {
				criteria.add(Restrictions.lt(key, value[0]));
			} else if (((String) value[1]).equals(SearchListCriteria.NE)) {
				criteria.add(Restrictions.ne(key, value[0]));
			} else if (((String) value[1]).equals(SearchListCriteria.IN)) {
				criteria.add(Restrictions.in(key, (Object[]) value[0]));
			}
		}
		Transaction transaction = session.beginTransaction();
		List<Itemtype> list = new ArrayList<Itemtype>();
		try {
			list = criteria.list();
			transaction.commit();
		} catch (HibernateException e) {
			for (String keyexception : keys) {
				log.info(keys);
			}
			throw e;
		} finally {
			log.info(SESSION_CLOSED);
			session.flush();
			HibernateUtil.closeSession();
		}
		return list;
	}
}